package com.example.fw;

import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import com.example.tests.ContactData;
import com.example.tests.GroupData;
import com.example.utils.ListOf;
import com.example.utils.SortedListOf;

public class ContactHelper extends WebDriverHelperBase{

	public static boolean CREATION = true;
	public static boolean MODIFICATION = false;
	
	public ContactHelper(ApplicationManager manager) {
		super(manager);
	}
	
	private SortedListOf<ContactData> cachedContacts;
	
	public SortedListOf<ContactData> getContacts() {
		if (cachedContacts == null) {
			rebuildCache();
		}
		return  cachedContacts;
	}
	
	public void rebuildCache() {
		cachedContacts = new SortedListOf<ContactData>(manager.getHibernateHelper().listContacts());
	}

	public SortedListOf<ContactData> getUiContacts() {
		SortedListOf<ContactData> contactList = new SortedListOf<ContactData>();
		manager.navigateTo().mainPage();
		List<WebElement> rows = driver.findElements(By.xpath("//tr[@name='entry']"));
		for (WebElement row : rows) {
			List<WebElement> cells = row.findElements(By.tagName("td"));
			String inputText = cells.get(1).getText();
			contactList.add(new ContactData().withLastName(inputText));
		}
		return  contactList;
	}
	

	public ContactHelper createContact(ContactData contact, boolean formType) {
		manager.navigateTo().mainPage();
		initContactCreation();
		fillContactForm(contact, formType);
		submitContactCreation();
		returnToHomePage();
		rebuildCache();
		return this;
	}

	public ContactHelper deleteContact(int index) {
		manager.navigateTo().mainPage();
		editContact(index);
		submitContactDeletion();
		returnToHomePage();
		rebuildCache();
		return this;
		
	}
	
	public ContactHelper modifyContact(int index, ContactData contact, boolean formType) {
		manager.navigateTo().mainPage();
		editContact(index);
		fillContactForm(contact, formType);
		submitContactModification();
		returnToHomePage();
		rebuildCache();
		return this;	
	}
	
	
	//----------------------------------------------------------------------
	public ContactHelper initContactCreation() {
		click(By.linkText("add new"));
		return this;
	}

	public ContactHelper fillContactForm(ContactData contact, boolean formType) {
		type(By.name("firstname"), contact.getFirstname());
		type(By.name("lastname"), contact.getLastname());
		type(By.name("address"), contact.getAddress());
		type(By.name("home"), contact.getPhoneHome());
		type(By.name("mobile"), contact.getPhoneMobile());
		type(By.name("work"), contact.getPhoneWork());
		type(By.name("email"), contact.getEmail());
		type(By.name("email2"), contact.getSecondEmail());
		selectByText(By.name("bday"), contact.getBirthdayDay());
		selectByText(By.name("bmonth"), contact.getBirthdayMonth());
		type(By.name("byear"), contact.getBirthdayYear());
		if (formType == CREATION) {
			selectByText(By.name("new_group"), contact.getGroupName());
		} else {
			if (driver.findElements(By.name(("new_group"))).size() !=0){
				throw new Error("Group selector exists in contract modification form");
			}
		}
	    type(By.name("address2"), contact.getAddressGroup());
		type(By.name("phone2"), contact.getPhoneGroup());
		return this;
	}

	public ContactHelper submitContactCreation() {
		click(By.name("submit"));
		cachedContacts = null;
		return this;
	  }

	public ContactHelper returnToHomePage() {
		click(By.linkText("home page"));
		return this;
	}
	
	private void selectContactByIndex(int index) {
		int rowIndex = index;
		driver.findElements(By.xpath("//input[@name='selected[]']")).get(rowIndex).click();
	}
	
	public ContactHelper editContact(int index) {
		selectContactByIndex(index);
		int rowIndex = index;
		driver.findElements(By.xpath("//img[@alt='Edit']")).get(rowIndex).click();
		return this;
	}
	
	public ContactHelper submitContactDeletion() {
		click(By.xpath("//input[@value='Delete']"));
		cachedContacts = null;
		return this;
	}
	
	public ContactHelper submitContactModification() {
		click(By.xpath("//input[@value='Update']"));
		cachedContacts = null;
		return this;
	}

	// Получение списка контактов с главной странице
	public ListOf<String> getContactMaintable() {
		ListOf<String> сontacts = new ListOf<String>();	
		manager.navigateTo().mainPage();
		List<WebElement> rows = driver.findElements(By.xpath("//tr[@name='entry']"));
		for (WebElement row : rows) {
			List<WebElement> cells = row.findElements(By.tagName("td"));
			String name = cells.get(2).getText().trim() + " " + cells.get(1).getText().trim();
			name = name.trim();
			String phoneHome = cells.get(4).getText();
			сontacts.add(name + " " +phoneHome);
		}	
		return сontacts;
	}
	
	// Получение списка контактов со страницы print phones
	public ListOf<String> getContactPrintphones() {
		ListOf<String> сontacts = new ListOf<String>();	
		manager.navigateTo().printphonesPage();
		List<WebElement> cols = driver.findElements(By.xpath("//td[@valign='top']"));
		for (WebElement col : cols) {
			String contactInfo = col.getText();
			// разделяю строку до символа перевода строки
			String[] info = contactInfo.split("\\n");
			// Первый элемент массива, это фамилия и имя
			String name = info[0].substring(0, info[0].length()-1).trim();
			/* телефон заполняется по принципу, что отображается первое заполененое поле 
			 * из трех полей, если ни одно и этих полей не заполнено, то в списке всего 3 объекста.
			 * поэтому я и проверяю, что если  размер массива < или = 3, то вернуть пустую строку.
			*/
			String phoneHome = "";
			if (info.length == 3) {
				if (info[1].substring(0,1).equals("H") || info[1].substring(0,1).equals("M") || info[1].substring(0,1).equals("W")){
					info [1] = info[1].replaceAll("[ ]", "");
					phoneHome = info[1].substring(2);
				}
			} else if (info.length > 3){
				/* если заполнять телефон с пробелами, эти пробел удаляются в главной таблице, но остаются в таблице с телефонами
				 * поэтому перед формирование списка я их удаляю.
				 */
				info [1] = info[1].replaceAll("[ ]", "");
				phoneHome = info[1].substring(2);
			}
			сontacts.add(name + " " + phoneHome);
		}	
		return сontacts;
	}

	// Сравнение двух списков
	public boolean compareContacts (ListOf<String> contactMaintable, ListOf<String> contactPrintphones) {
		for(int i=0; i < contactMaintable.size(); i++){
			if(!contactMaintable.get(i).equals(contactPrintphones.get(i))){
				return false;
			}
		}
		return true;
	}
	
	public ContactData getEditUIContact() {
		ContactData contact = new ContactData();
		contact.setFirstname(getValue(By.name("firstname")));
		contact.setLastname(getValue(By.name("lastname")));
		contact.setAddress(getValue(By.name("address")));
		contact.setPhoneHome(getValue(By.name("home")));
		contact.setPhoneMobile(getValue(By.name("mobile")));
		contact.setPhoneWork(getValue(By.name("work")));
		contact.setEmail(getValue(By.name("email")));
		contact.setSecondEmail(getValue(By.name("email2")));
		contact.setBirthdayDay(getValue(By.name("bday")));
		contact.setBirthdayMonth(getValue(By.name("bmonth")));
		contact.setBirthdayYear(getValue(By.name("byear")));
		contact.setAddressGroup(getValue(By.name("address2")));
		contact.setPhoneGroup(getValue(By.name("phone2")));
		return contact;
	}

	
	public ContactData getEditContact(int index){
		SortedListOf<ContactData>  listContact = new  SortedListOf<ContactData>(manager.getHibernateHelper().listContacts());	
		return listContact.get(index);
	}
}
